package org.example;

import org.w3c.dom.*;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;

public class SimpleIoC {

    private Map<String, Object> beans = new HashMap<>();

    public SimpleIoC(String configLocation) {
        loadConfig(configLocation);
    }

    private void loadConfig(String location) {
        try {
            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
            DocumentBuilder builder = factory.newDocumentBuilder();
            Document doc = builder.parse(getClass().getClassLoader().getResourceAsStream(location));
            NodeList beanNodes = doc.getDocumentElement().getChildNodes();

            // 1) 先创建实例
            for (int i = 0; i < beanNodes.getLength(); i++) {
                Node node = beanNodes.item(i);
                if (node.getNodeType() == Node.ELEMENT_NODE && "bean".equals(node.getNodeName())) {
                    Element elem = (Element) node;
                    String id = elem.getAttribute("id");
                    String className = elem.getAttribute("class");
                    Class<?> clazz = Class.forName(className);

                    // 默认无参构造
                    Constructor<?> ctor = clazz.getConstructor();
                    Object instance = ctor.newInstance();
                    beans.put(id, instance);
                }
            }

            // 2) 设置属性（简单属性：String、int 等）
            for (int i = 0; i < beanNodes.getLength(); i++) {
                Node node = beanNodes.item(i);
                if (node.getNodeType() == Node.ELEMENT_NODE && "bean".equals(node.getNodeName())) {
                    Element elem = (Element) node;
                    String id = elem.getAttribute("id");
                    Object bean = beans.get(id);

                    NodeList props = elem.getElementsByTagName("property");
                    for (int j = 0; j < props.getLength(); j++) {
                        Element prop = (Element) props.item(j);
                        String propName = prop.getAttribute("name");
                        String propValue = prop.getAttribute("value");

                        // 简单类型注入
                        Field field = bean.getClass().getDeclaredField(propName);
                        field.setAccessible(true);
                        if (field.getType() == String.class) {
                            field.set(bean, propValue);
                        } else if (field.getType() == int.class || field.getType() == Integer.class) {
                            field.set(bean, Integer.parseInt(propValue));
                        }
                        // 如需注入其他引用类型，可扩展
                    }
                }
            }
        } catch (Exception e) {
            throw new RuntimeException("Failed to load IOC config", e);
        }
    }

    @SuppressWarnings("unchecked")
    public <T> T getBean(String id) {
        return (T) beans.get(id);
    }

    public static void main(String[] args) {
        SimpleIoC container = new SimpleIoC("beans.xml");
        Product product = container.getBean("product");
        Student student = container.getBean("student");

        System.out.println("Product: " + product);
        System.out.println("Student: " + student);
    }
}